home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- *
- * NSSDC/CDF Window Function Library.
- *
- * Version 2.0, 4-Mar-92, ST Systems (STX)
- *
- * Modification history:
- *
- * V1.0 29-Jan-91, C Goettsche
- * D Grogan
- * H Leckner Original version (for CDF V2.0).
- * V1.1 25-Jun-91, J Love Removed 'kb_def_user.h'.
- * V1.2 28-Jun-91, J Love TRUE/FALSE.
- * V2.0 4-Mar-92, J Love Modified for IBM-PC port. CDF V2.2.
- * H Leckner
- *
- ******************************************************************************/
-
- #include "wfl.h"
- #include <stdlib.h>
- #include <string.h>
-
- #include "cdfdist.h"
- #include "kb_def.h"
- #include "utility.h"
- /*
- * development debug switches
- */
- #define KEYPADBUG (0)
- #define DEBUG (0)
- #define DEBUG1 (0)
- #define DEBUG2 (0)
- #define DEBUG3 (0)
- #define DEBUG4 (0)
-
- /*
- * these debug WFL_load_menu scrolling capability
- */
- #define MARKLOAD (0) /* send slow-motion message on each put_char */
- #define UPDATE_ON (1) /* display_update on or off */
-
-
- #define MAX_MENUS 35 /* Constants for */
- #define TRANSIENT 0 /* WFL_popup_menu() */
-
- #define GP (**c)
- #define CP (*c)
-
- #define CURSOR_OFF 1
- #define CURSOR_ON 0
-
- /* The next mark, clsPAREN, will only be used to close function headers.
- This has been done so that the *.REF can be extracted and used
- as the ANSI function prototype list by redefining clsPAREN as );
- The prototypes (file WFL.REF) is included by WFL.H so the define
- below must come after the include for "wfl.c"
- */
-
- #define clsPAREN )
-
- /*CodeRef-mark*/
- /*
- * Global screen functions
- */
-
- #if defined(unix)
- void left_justify();
- #else
- void left_justify (char field[], int len);
- #endif
- /*CodeRef-mark*/
-
- void WFL_init()
- /*
- * Call this once before using any of the other WFL functions to
- * initialize the global_struct.
- * This function intializes the screen driver and keyboard controller.
- * The pointers to these devices are held in a structure which is allocated
- * and passed back to the caller. This pointer must be passed into most
- * WFL routines.
- */
- /*CodeRef-mark*/
- {
- create_pasteboard(); /* OK as is for vms 5 SMG; pasteboard always
- before keyboard - grogan 12/21/89 */
-
- #ifdef vms
- set_keypad_mode (1L); /* 1= application keyboard */
- /* 0= numeric keyboard */
- #endif
-
- } /* end WFL_init */
-
-
- /*CodeRef-mark*/
-
- void WFL_close()
- /*
- * This function terminates a session with the WFL package and should
- * be called after the interface is completed.
- * c is the pointer used when WFL_init() was called.
- */
- /*CodeRef-mark*/
- {
- int erase_mode;
- erase_mode = 1;
- delete_pasteboard(erase_mode);
-
- } /* end WFL_close */
-
-
- /*CodeRef-mark*/
-
- #if defined(vms)
- void WFL_message_init(mess_ptr)
- struct window_struct *mess_ptr;
- /*
- * This function initializes a message window pointed to by mess_ptr
- * so that operating system messages will be trapped and sent to that
- * window. Otherwise, system messages would appear wherever the cursor
- * happened to be.
- */
- /*CodeRef-mark*/
- {
-
- WINDOWid mess_id;
-
- mess_id = (*mess_ptr).wind_id;
-
- enable_trap(mess_id);
-
- } /* end WFL_message_init */
- #endif
-
- /*CodeRef-mark*/
-
- void WFL_message_display (c ,message, beep)
- struct window_struct *c;
- char message[];
- int beep;
- /*
- * This function displays the string message[] in the message window c.
- * The "beep" parameter determines wheteher the terminal beeps or not
- * when the message is sent. beep should be one of the predefined
- * constants BEEP or NOBEEP.
- */
- /*CodeRef-mark*/
- {
- int erase_mode = 0;
- int video_type = NORMAL;
- int len;
- int start_row = 1;
- int start_col = 1;
-
- len = strlen(message);
- put_chars(CP.wind_id, message, len, start_row, start_col,
- erase_mode, video_type);
- if (beep)
- #if defined(vms)
- ring_bell (CP.wind_id);
- #else
- ring_bell();
- #endif
- } /* end WFL_message_display */
-
-
- /*CodeRef-mark*/
-
- void WFL_begin_screen_update ()
- /*
- * Prepare screen for updating in a buffer.
- */
- /*CodeRef-mark*/
- {
- #if defined(vms)
- begin_pasteboard_update();
- #endif
- } /* end WFL_begin_screen_update */
-
- /*CodeRef-mark*/
-
- void WFL_end_screen_update ()
- /*
- * This function flushes the buffer after a call to WFL_begin_screen_update.
- * Used to maintain data abstraction.
- */
- /*CodeRef-mark*/
- {
- #if defined(vms)
- end_pasteboard_update();
- #endif
- } /* end WFL_end_screen_update */
-
-
-
- /*CodeRef-mark*/
- /*
- * General window functions, for all window types
- */
-
- /*CodeRef-mark*/
-
-
- /*CodeRef-mark*/
-
- void WFL_create_window( c)
- struct window_struct *c ;
- /*
- * This function will initialize a window for further use in WFL.
- * The window_struct c should have its elements num_rows and num_cols
- * assigned before calling WFL_create_window().
- */
- /*CodeRef-mark*/
- {
- WINDOWid vid;
- int disp_type;
- int video_type;
-
- disp_type = 1;
- video_type = NORMAL; /* changed from _ONE (BOLD) */
- create_virtual_display(CP.num_rows+ROW_OFFSET, CP.num_cols+COL_OFFSET,
- &vid, disp_type, video_type);
- CP.wind_id = vid;
-
- } /* end WFL_create_window */
-
- /*CodeRef-mark*/
-
- void WFL_delete_window(c)
- struct window_struct *c ;
- /*
- * Remove the window for good -- complement of WFL_create_window.
- * Not the same as WFL_erase_window().
- * The window cannot be used again without re-creating it.
- * See WFL_erase_display to "clear" the window.
- */
- /*CodeRef-mark*/
- {
- WINDOWid vid;
-
- vid = CP.wind_id;
- delete_virtual_display( vid );
-
- } /* end WFL_delete_window */
-
-
-
- /*CodeRef-mark*/
-
- void WFL_draw_window (window_ptr)
- struct window_struct *window_ptr;
- /*
- * This function draws a labeled window on the screen at the
- * location and with the dimensions given within the window_struct.
- * The label element in the window_struct is used to create
- * a label for the window border. You may use a null string label for an
- * unlabeled window.
- * At this point the window is an empty box which may now be written to.
- * The drawn window will occlude other text on the screen until the
- * window is moved or erased.
- */
- /*CodeRef-mark*/
- {
- int len;
- /*
- #if !defined(vms)
- begin_display_update((*window_ptr).wind_id);
- #endif
- */
- paste_virtual_display((*window_ptr).wind_id,
- (*window_ptr).start_row-ROW_OFFSET,(*window_ptr).start_col-COL_OFFSET);
-
- len = strlen((*window_ptr).label);
- if (len > 0)
- label_border((*window_ptr).wind_id, (*window_ptr).label, len);
- /*
- #if |defined(vms)
- end_display_update((*window_ptr).wind_id);
- #endif
- */
- } /* end WFL_draw_window */
-
-
- /*CodeRef-mark*/
-
- void WFL_erase_window (window_ptr)
- struct window_struct *window_ptr;
- /*
- * This function erases window (pointed to by window_ptr) from
- * the video display -- the inverse of WFL_draw_window().
- * Not the same as WFL_erase_display() or WFL_delete_window().
- * Any text on the screen which had been occluded by the window will
- * be restored to the screen.
- * The erased window still exists and can be displayed again
- * with WFL_draw_window() until it is deleted with WFL_delete_window().
- */
- /*CodeRef-mark*/
- {
- unpaste_virtual_display((*window_ptr).wind_id);
-
- } /* end WFL_erase_window */
-
-
-
- /*CodeRef-mark*/
-
- void WFL_erase_display (window_ptr)
- struct window_struct *window_ptr;
- /*
- * This function will erase (clear) the display in the window --
- * that is, it will amke the interior of the window all blanks.
- * The window and its border still remain active and displayed.
- * Not the same as WFL_erase_window() or WFL_delete_window().
- */
- /*CodeRef-mark*/
- {
- erase_display ((*window_ptr).wind_id, 1, 1,
- (*window_ptr).num_rows,
- (*window_ptr).num_cols);
- } /* end WFL_erase_display */
-
-
-
- /*CodeRef-mark*/
- void WFL_begin_display_update (window_ptr)
- struct window_struct *window_ptr;
- /*
- * This function starts buffering of output to the window
- * for smoother onscreen appearance. Actual device output
- * is not done until you call WFL_end_display_update().
- * Return value: void.
- */
- /*CodeRef-mark*/
- {
- begin_display_update((*window_ptr).wind_id);
- }
-
- /*CodeRef-mark*/
-
- void WFL_end_display_update (window_ptr)
- struct window_struct *window_ptr;
- /*
- * This function flushes the buffering started by
- * WFL_begin_display_update().
- * Return value: void.
- */
- /*CodeRef-mark*/
- {
- end_display_update((*window_ptr).wind_id);
- }
- #if !defined(vms)
- void WFL_end_display_update_nobox(window_ptr)
- struct window_struct *window_ptr;
- /*
- * This function flushes the buffering started by
- * WFL_begin_display_update().
- * this is a special version needed because of labels being overwritten
- * in some cases
- * Return value: void.
- */
- /*CodeRef-mark*/
- {
- end_display_update_nobox((*window_ptr).wind_id);
- }
- #endif
-
- /*CodeRef-mark*/
-
- void WFL_change_window_length ( c, length)
- struct window_struct *c;
- int length;
- /*
- * Rewrite length (num_rows) of window.
- * Used to maintain data abstraction.
- */
- /*CodeRef-mark*/
- {
- CP.num_rows = length;
- } /* end WFL_change_window_length */
-
-
- /*CodeRef-mark*/
-
- void WFL_change_window_width ( c, width)
- struct window_struct *c;
- int width;
- /*
- * Rewrite width (num_cols) of window.
- * Used to maintain data abstraction.
- */
- /*CodeRef-mark*/
- {
- CP.num_cols = width;
- } /* end WFL_change_window_length */
-
-
- /*CodeRef-mark*/
-
- void WFL_change_window_loc ( c, x, y)
- struct window_struct *c;
- int x;
- int y;
- /*
- * Alter starting location of window (x is start_col; y is start_row).
- * Used to maintain data abstraction.
- */
- /*CodeRef-mark*/
-
- {
- CP.start_col = x;
- CP.start_row = y;
- } /* end WFL_change_window_loc */
-
-
-
-
- /*CodeRef-mark*/
- /*
- * Menu functions
- */
-
-
- /*CodeRef-mark*/
-
- /*CodeRef-mark*/
-
- void WFL_menu_element (data_ptr, element_ptr, num_elements, number, rcode )
- char data_ptr[];
- struct menu_element_struct *element_ptr[];
- int num_elements;
- int *number;
- int *rcode;
- /*
- * This function tells the index number of a menu element string.
- * The string to look for is passed in by data_ptr and is compared
- * to all elements strings pointed to in element_ptr[].
- * The number of elements must be given.
- * If a match found, the element number is returned in the
- * variable "number", otherwise a -1 is returned by rcode.
- * This function is the inverse of WFL_menu_string().
- *
- */
- /*CodeRef-mark*/
- {
- int element_num;
- int len;
- int check;
- *rcode = 0;
- len = strlen(data_ptr);
- if(len > 0)
-
- {
- for (element_num = 0; element_num < num_elements; ++element_num)
- {
- check = strcmp(data_ptr, (*element_ptr[element_num]).label);
- if(check == 0)
- {
- *number = element_num;
- return;
- }
- }
- *rcode = -1;
- }
-
- } /* end WFL_menu_element */
-
-
- /*CodeRef-mark*/
-
- void WFL_menu_string (index, element_ptr, string)
- int index;
- struct menu_element_struct *element_ptr[];
- char string[];
- /*
- * This function copies the menu element specified by index into
- * the array string[].
- * rcode is not used.
- * This function is the inverse of WFL_menu_element().
- */
- /*CodeRef-mark*/
- {
- string = strcpy(string, (*element_ptr[index]).label);
- } /* end WFL_menu_string */
-
-
-
- /*CodeRef-mark*/
-
- void WFL_load_menu (element_ptr, num_elements, window_ptr,
- rowOffset, colOffset)
- struct menu_element_struct *element_ptr[];
- int num_elements;
- struct window_struct *window_ptr;
- int rowOffset;
- int colOffset;
- /*
- * This function loads a menu.
- */
- /*CodeRef-mark*/
- {
- int element_num;
- int erase_mode;
- int video_type;
- int len;
-
- int srow, scol;
-
- #if MARKLOAD
- char message[200];
- long j;
- #endif
-
- erase_mode = 0;
- video_type = NORMAL;
-
- for (element_num = 0;
- element_num < num_elements; element_num++)
- {
- srow = (*element_ptr[element_num]).start_row - rowOffset;
-
- /* if ( (srow > 0) && (srow <= SCREEN_HEIGHT+1) ) */
- if ( (srow > 0) && (srow <= (*window_ptr).num_rows))
- {
- len = strlen((*element_ptr[element_num]).label);
- scol = (*element_ptr[element_num]).start_col - colOffset;
- put_chars((*window_ptr).wind_id,
- (*element_ptr[element_num]).label, len,
- srow, scol,
- erase_mode, video_type);
- }
- #if MARKLOAD
- sprintf (message," (load_stat) [%ld] at (%ld,%ld)",element_num, srow, scol);
- MESS_display (" ",0);
- for (j=0; j<35; j++) MESS_display (message,0);
- #endif
-
- }
-
- } /* end WFL_load_menu */
-
-
- /*CodeRef-mark*/
-
- long int WFL_read_menu (element_ptr, num_elements, window_ptr,
- menu_choice, windowHead, highlight)
- struct menu_element_struct *element_ptr[];
- int num_elements;
- struct window_struct *window_ptr;
- int *menu_choice;
- int *windowHead;
- int highlight;
- /*
- Modification, October 1988, Dan Grogan, to allow a
- "DARK" menu, one without a highlight bar.
- Argument highlight is a boolean, if true, then highlight ON.
- If false, then highlight is OFF.
-
- Return value: filtered keyboard code of KB_ or KBM_ set.
- */
- /*CodeRef-mark*/
- {
- int element_num;
- int old_element;
- int num_rows;
- int num_cols;
- char value;
- int keyWas;
-
- int winTop, winBot, winHgt;
- int rowOffset, colOffset;
- int nScrolls, k;
-
- element_num = *menu_choice;
-
- winTop = *windowHead;
- winHgt = (*window_ptr).num_rows;
- winBot = winTop + winHgt -1;
-
- rowOffset = (*element_ptr[winTop]).start_row -1;
- colOffset = 0;
- /*** DEVELOPMENT NOTE:
- colOffset should be 0 until horizontal scrolling implemented:
- colOffset = (*element_ptr[element_num]).start_col -1;
- ***/
-
- num_cols = strlen((*element_ptr[element_num]).label);
- num_rows = 1;
-
- if (highlight) highlight_on((*window_ptr).wind_id,
- (*element_ptr[element_num]).start_row -rowOffset,
- (*element_ptr[element_num]).start_col -colOffset,
- num_rows, num_cols);
-
- keyWas = 0;
-
- #if defined(vms)
- set_cursor_mode (CURSOR_OFF);
- #endif
- while ( (keyWas != KB_CONTEXT_HELP)
- && (keyWas != KBM_SELECT)
- && (keyWas != KBM_BACK)
- && (keyWas != KBM_HELP)
- && (keyWas != KBM_LEFT)
- && (keyWas != KBM_RIGHT)
- && (keyWas != KBM_QUIT)
- && (keyWas != KBM_EXIT) )
- {
-
- place_cursor_abs((*window_ptr).wind_id,
- (*element_ptr[element_num]).start_row -rowOffset,
- (*element_ptr[element_num]).start_col -colOffset);
-
- #ifdef vms
- get_input(&value, &keyWas);
- #endif
- #if defined(unix) | defined(__MSDOS__)
- get_input ((*window_ptr).wind_id, &value, &keyWas);
- #endif
-
- /*
- Have to use this because ALPHA U and D are used for paging
- */
- if( value == KBM_PREVSCRN ||
- value == KBM_prevscrn ||
- value == KBM_NEXTSCRN ||
- value == KBM_nextscrn)
- keyWas = value;
-
- WFL_begin_display_update (window_ptr);
-
- switch (keyWas)
- {
- case KBM_LEFT:
- case KBM_RIGHT:
- case KBM_BACK:
- case KBM_QUIT:
- case KBM_EXIT:
- *menu_choice = element_num;
- break;
-
- case KB_CONTEXT_HELP:
- case KBM_SELECT:
- case KBM_HELP:
- *menu_choice = element_num;
- *windowHead = winTop;
- break;
-
- case KB_PAD7:
- case KBM_PREVSCRN:
- case KBM_prevscrn:
- case KBM_UP:
-
-
- if ( (keyWas == KBM_PREVSCRN) ||(keyWas == KBM_prevscrn) ||
- (keyWas == KB_PAD7) )
- nScrolls = (*window_ptr).num_rows -1;
- else
- nScrolls = 1;
-
- for (k=0; k<nScrolls; k++)
- {
-
- old_element = element_num;
-
- if ( (keyWas == KBM_PREVSCRN) || (keyWas == KBM_prevscrn) ||
- (keyWas == KB_PAD7) )
- /* no wrap on page up */
- {
- if (element_num > 0)
- element_num --;
- else
- element_num = 0;
- }
- else
- {
- if (element_num > 0)
- element_num --;
- else
- element_num = num_elements -1;
- }
-
- if (highlight) highlight_off ( (*window_ptr).wind_id,
- (*element_ptr[old_element]).start_row -rowOffset,
- 1, 1,
- strlen((*element_ptr[old_element]).label) );
-
-
- if (element_num < winTop)
- {
- winTop = element_num;
- winBot = winTop + winHgt -1;
-
- WFL_erase_display (window_ptr);
- rowOffset--;
-
- WFL_load_menu (element_ptr, num_elements, window_ptr,
- rowOffset, colOffset);
- }
-
- else if (element_num > winBot) /* wrap top-to-bot */
- {
- winBot = element_num;
- winTop = winBot -winHgt +1;
-
- WFL_erase_display (window_ptr);
- rowOffset = (*element_ptr[winTop]).start_row -1;
-
- WFL_load_menu (element_ptr, num_elements, window_ptr,
- rowOffset, colOffset);
- }
-
- if (highlight) highlight_on ( (*window_ptr).wind_id,
- (*element_ptr[element_num]).start_row -rowOffset,
- 1, 1,
- strlen((*element_ptr[element_num]).label) );
-
- } /* end for k to nScrolls */
-
- break;
-
-
- case KB_PAD4:
- case KBM_NEXTSCRN:
- case KBM_nextscrn:
- case KBM_DOWN:
-
- if ( (keyWas == KBM_NEXTSCRN) || (keyWas == KBM_nextscrn) ||
- (keyWas == KB_PAD4) )
- nScrolls = (*window_ptr).num_rows -1;
- else
- nScrolls = 1;
-
- for (k=0; k<nScrolls; k++)
- {
-
- old_element = element_num;
-
- if ( (keyWas == KBM_NEXTSCRN) || (keyWas == KBM_nextscrn) ||
- (keyWas == KB_PAD4) )
- /* no wrap on page down */
- {
- if (element_num < num_elements -1)
- element_num++;
- else
- element_num = num_elements -1;
- }
- else
- {
- if (element_num < num_elements-1)
- element_num++;
- else
- element_num = 0;
- }
-
- if (highlight) highlight_off ( (*window_ptr).wind_id,
- (*element_ptr[old_element]).start_row -rowOffset,
- 1, 1,
- strlen((*element_ptr[old_element]).label) );
-
-
- if (element_num < winTop) /* wrap bot-to-top */
- {
- winTop = element_num;
- winBot = winTop + winHgt -1;
-
- WFL_erase_display (window_ptr);
- rowOffset = (*element_ptr[winTop]).start_row -1;
-
- WFL_load_menu (element_ptr, num_elements, window_ptr,
- rowOffset, colOffset);
- }
-
- if (element_num > winBot)
- {
- winBot = element_num;
- winTop = winBot -winHgt +1;
-
- WFL_erase_display (window_ptr);
- rowOffset++;
-
- WFL_load_menu (element_ptr, num_elements, window_ptr,
- rowOffset, colOffset);
- }
-
- if (highlight) highlight_on ( (*window_ptr).wind_id,
- (*element_ptr[element_num]).start_row -rowOffset,
- 1, 1,
- strlen((*element_ptr[element_num]).label) );
-
- } /* end for k to nScrolls */
-
- break;
-
- case REDRAW:
- redraw_screen();
- break;
-
- } /* end switch(keyWas) */
- #if !defined(vms)
- WFL_end_display_update_nobox(window_ptr);
- #else
- WFL_end_display_update(window_ptr);
- #endif
- } /* end while (keyWas != some exit condition) */
- #if defined(vms)
- set_cursor_mode (CURSOR_ON);
- #endif
- return (keyWas);
-
- } /* end WFL_read_menu */
-
-
- /*CodeRef-mark*/
-
-
- /*
- * Dynamic menu functions
- */
-
-
- /*CodeRef-mark*/
-
- /*CodeRef-mark*/
-
-
-
-
- /*CodeRef-mark*/
-
- long int WFL_new_dyna_window (window, banner)
- struct window_struct **window;
- char *banner;
- /*
- * Allocate memory for one transient window and copy the
- * banner string into the label field of the window.
- * No protection against too-long banner string.
- * Return value: 0 = successful allocation, -1 = failure.
- */
- /*CodeRef-mark*/
- {
- *window = ((struct window_struct *) malloc(sizeof(struct window_struct)));
- if (*window == NULL)
- {
- printf ("\n (new_dyna_window): NULL pointer from allocate dyna window.");
- return (-1L);
- }
- strcpy ( (**window).label, banner);
-
- #if DEBUG1
- printf ("\n (new_dyna_window): (**window).label = %s", (**window).label);
- #endif
-
- return (0L);
- } /* end WFL_new_dyna_window */
-
-
-
- /*CodeRef-mark*/
-
- void WFL_delete_dyna_window (window)
- struct window_struct *window;
-
- {
- free ((char *) window);
- } /* end WFL_delete_dyna_window */
-
-
-
-
- void WFL_set_dyna_window (startRow, startCol, maxRows, element_list,
- window)
- int startRow;
- int startCol;
- int maxRows;
- char *element_list[];
- struct window_struct *window;
- /*
- * Initializes a transient window for displaying the element_list[]:
- * Set window.start_row equal to startRow.
- * Set window.start_col equal to startCol.
- * Set window.num_cols equal to the length of the
- * longest string in the list, limited by SCREEN_WIDTH.
- * Set window.num_rows equal to the number of items
- * in the list, limited by maxRows.
- * maxCols is not in use -- later to be a limit for num_cols.
- *
- * If the resultant window would not show completely on the video
- * screen, window.start_row and window.start_col will be adjusted
- * so that as much of the window as possible is displayed.
- * That is, the window's upper-left corner gets moved toward the
- * position (1,1).
- */
- /*CodeRef-mark*/
- {
- (*window).num_rows = string_count (element_list);
- if ((*window).num_rows > maxRows)
- (*window).num_rows = maxRows;
-
- (*window).num_cols = longest_string (element_list);
- if ( strlen((*window).label) > (*window).num_cols )
- (*window).num_cols = strlen((*window).label);
-
- /*
- * adjust start row and column if necessary --
- * make it stay in the screen, if possible.
- */
- if ( (startRow + (*window).num_rows) > SCREEN_HEIGHT)
- (*window).start_row = SCREEN_HEIGHT -(*window).num_rows;
- else
- (*window).start_row = startRow;
-
- if ( (startCol + (*window).num_cols) > SCREEN_WIDTH)
- (*window).start_col = SCREEN_WIDTH -(*window).num_cols;
- else
- (*window).start_col = startCol;
-
- if ( (*window).start_row < 2L) (*window).start_row = 2L;
- if ( (*window).start_col < 2L) (*window).start_col = 2L;
-
- WFL_create_window (window);
-
- } /* end WFL_set_dyna_window */
-
-
-
- /*CodeRef-mark*/
-
- long int WFL_new_dyna_elem_list (menu_element_ptr, element_list)
- struct menu_element_struct *menu_element_ptr[];
- char *element_list[];
- /*
- * This function creates a menu list form a text list.
- */
- /*CodeRef-mark*/
- {
- int num_elements;
- int k;
-
- num_elements = string_count (element_list);
-
- for (k=0; k<num_elements; k++)
- {
-
- #if DEBUG1
- printf ("\n (new_elem_list): menu_element_ptr[%ld] = %ld",
- k, menu_element_ptr[k]);
- #endif
-
- menu_element_ptr[k] = ((struct menu_element_struct *)
- malloc (sizeof(struct menu_element_struct)));
- if (menu_element_ptr[k] == NULL)
- {
- printf ("\n WFL: NULL pointer trying to allocate menu element.");
- return (-1L);
- }
-
- (*menu_element_ptr[k]).start_row = k +1;
- (*menu_element_ptr[k]).start_col = 1;
- strcpy ( (*menu_element_ptr[k]).label, element_list[k]);
-
- } /* end k-loop */
-
- return (0L);
- } /* end WFL_new_dyna_elem_list */
-
-
- /*CodeRef-mark*/
-
- struct menu_element_struct **WFL_new_dyna_menu (element_list)
- char *element_list[];
- /* This function does the following:
- * 1. Makes a menu selection list from the element_list.
- * 2. Allocates memory for one menu pointer-list and
- * memory for all the elements pointed-to by the list.
- * element_list[] is a WFL 'null-terminated array of strings'.
- * 3. Sets row and col for each element.
- * 4. Loads the label for each element.
- *
- * Return value:
- * a pointer to the array of pointers, or for failure, NULL.
- * This function is used in building dynamic menus.
- * You must call WFL_delete_dyna_menu() to assure proper
- * deallocation of the dynamic menu.
- */
- /*CodeRef-mark*/
- {
- int num_elements;
- /*int k;*/
-
- struct menu_element_struct **ptr;
-
- num_elements = string_count (element_list);
-
- ptr = ((struct menu_element_struct **)
- calloc(num_elements, sizeof(struct menu_element_struct * )));
- if (ptr == NULL) return NULL;
-
- WFL_new_dyna_elem_list (ptr, element_list);
- return ptr;
-
- } /* end WFL_new_dyna_menu */
-
-
- void WFL_delete_dyna_menu (ptr, element_list)
- struct menu_element_struct **ptr;
- char *element_list[];
- /*
- * This function dellocates memory for one menu pointer-list and
- * memory for all the elements pointed-to by the list.
- * A return value of 0 indicates success, non-zero is failure.
- * Call it to deallocate memory after using WFL_new_dyna_menu()
- * The parameter "ptr" is a pointer-pointer which has been set by
- * WFL_new_dyna_menu() and the element_list[] is the same one used
- * when the new menu was created.
- */
- /*CodeRef-mark*/
- {
- int num_elements;
- int k;
-
- /*int status;*/
-
- num_elements = string_count (element_list);
-
- for (k=0; k<num_elements; k++)
- {
- free ( (struct menu_element_struct *) ptr[k]);
- }
- /* free ((struct menu_struct_type **) ptr); can't find this structure */
- free ((struct menu_element_struct**) ptr);
- } /* end WFL_delete_dyna_menu */
-
-
- int WFL_popup_menu (startRow, startCol, maxRows,
- banner, element_list, user_selection, menu_id, highlight)
- int startRow;
- int startCol;
- int maxRows;
- char *banner;
- char *element_list[];
- long int *user_selection;
- int menu_id;
- int highlight;
- /*
- *
- * WFL_popup_menu pops up a menu on-the-fly and returns the index
- * of the element selected by the user in the variable user_selection.
- *
- * startRow and startCol position the upper-left corner of the menu
- * window on the screen.
- *
- * maxRows limits the height of the window -- if there are fewer
- * than maxRows items in element_list[], the window will be sized
- * to exactly hold the list.
- * maxCols is not being used yet -- pass any value.
- *
- * banner is the menu-window label string.
- *
- * element_list is a WFL 'null-terminated array of strings'.
- *
- * WFL_popup_menu creates a transient window and creates a menu selection
- * list from the element_list[] and
- * initializes them both and then displays the menu, waiting for
- * the user to make a selection.
- * After the selection, the window is erased and deleted and
- * transient memory is deallocated.
- *
- * ---
-
- --- Mods, October 1988, Dan Grogan
-
- Menus may now remain open (and on-screen) while the user is
- active in another menu or form because of the menu_id argument.
- The menu_id is an integer constant and the key to static state
- variables that record the current state of an open menu.
-
- Other than the "transient-menu", an opened menu will remain open
- until the user presses the KBM_QUIT key. For instance, if the
- user is in menu 1 (menu_id=1) and SELECTs item 5, controls
- returns to the caller with the state of menu 1 saved, and menu 1
- still on-screen. When WFL_popup_menu is called again for menu
- 1, its status is still open and the selection bar returns to
- where it was last, at item 5. Only when the user QUITs menu 1
- will menu 1 be removed from the screen and deallocated. And its
- recorded state will be marked as closed.
- The TRANSIENT_MENU (menu_id=0) is a special case and never remains
- open; all returns to the caller close the menu.
-
- The highlight argument now allows a "dark" menu, one
- without highlight bar -- dark menu with highlight FALSE;
- regular menu with highlight = TRUE. The dark menu may be used
- as a scrollable informnation box.
- *
- * Return value: filtered keyboard code from WFL_read_menu().
- */
- /*CodeRef-mark*/
- {
- /*char message[200];*/
- int real_row, real_col;
-
- /*int stat;*/
- int keyWas;
- int num_elements;
-
- /*
- * These values are now being saved for returning the state of an
- * menu left open....
- */
-
- static struct menu_element_struct **menu_element_ptr[MAX_MENUS]=
- {0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0};
-
- static struct window_struct *window_ptr[MAX_MENUS]=
- {0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0};
-
- static int menuChoice[MAX_MENUS] =
- {0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0};
-
- static int windowHead[MAX_MENUS] =
- {0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0};
-
-
- if ( (window_ptr[menu_id] == 0) || /* the requested menu is not open */
- (menu_id == TRANSIENT) )
- {
-
- WFL_new_dyna_window (&window_ptr[menu_id], banner);
-
- WFL_set_dyna_window (startRow, startCol, maxRows,
- element_list, window_ptr[menu_id] );
-
- /* Make a menu selection list from the element_list */
- menu_element_ptr[menu_id] = WFL_new_dyna_menu (element_list);
-
- WFL_draw_window (window_ptr[menu_id]);
-
- WFL_load_menu (menu_element_ptr[menu_id], string_count(element_list),
- window_ptr[menu_id], windowHead[menu_id], 0);
- }
-
- num_elements = string_count(element_list);
-
- do /* until user key is acceptable */
- {
- keyWas = WFL_read_menu (
- menu_element_ptr[menu_id],
- num_elements,
- window_ptr[menu_id],
- &menuChoice[menu_id],
- &windowHead[menu_id],
- highlight );
- }
- while ( (keyWas != KB_CONTEXT_HELP) &&
- (keyWas != KBM_SELECT) &&
- (keyWas != KBM_LEFT) &&
- (keyWas != KBM_RIGHT) &&
- (keyWas != KBM_QUIT) &&
- (keyWas != KBM_HELP) &&
- (keyWas != KBM_EXIT) );
-
- *user_selection = menuChoice[menu_id];
-
- /*
- * If the key was EXIT the current menu or
- * if the menu is the transient menu (id = 0), the menu will be closed.
- * If the key was SELECT, HELP, QUIT, or other, the menu will be left
- * open and may be re-entered with the state the same.
- */
-
- if ( (keyWas == KBM_EXIT) ||
- (menu_id == TRANSIENT) )
- {
- /* get rid of the current window and menu */
-
- WFL_erase_window (window_ptr[menu_id]);
-
- WFL_delete_dyna_window (window_ptr[menu_id]);
-
- WFL_delete_dyna_menu (menu_element_ptr[menu_id],
- element_list);
- menuChoice[menu_id] = 0;
- windowHead[menu_id] = 0;
- window_ptr[menu_id] = 0;
- menu_element_ptr[menu_id] = 0;
-
- } /* end of get rid of window */
- else
- {
- /* remember the position of the select bar -- (keep the menu open) */
-
- real_row = window_ptr[menu_id]->start_row;
- real_col = window_ptr[menu_id]->start_col;
-
-
- menu_bar_last_at_row (real_row);
- menu_bar_last_at_col (real_col);
-
- } /* end of keep menu open */
-
- return (keyWas);
-
- } /* end WFL_popup_menu */
-
-
- /*CodeRef-mark*/
-
-
-
-
- /*CodeRef-mark*/
- /*
- * Form functions
- */
-
-
- /*CodeRef-mark*/
-
- /*CodeRef-mark*/
-
- void WFL_load_form (element_ptr, num_elements, window_ptr)
- struct form_element_struct *element_ptr[];
- int num_elements;
- struct window_struct *window_ptr;
- /*
- * Initialize the form. After window is drawn this function is
- * called to load each element of a form into the window.
- */
- /*CodeRef-mark*/
- {
- int element_num;
- int erase_mode;
- int video_type;
- int len;
-
- erase_mode = 0;
- video_type = NORMAL;
- for (element_num = 0; element_num < num_elements; ++element_num)
- {
-
- len = strlen((*element_ptr[element_num]).label);
- put_chars((*window_ptr).wind_id,
- (*element_ptr[element_num]).label, len,
- (*element_ptr[element_num]).start_row,
- (*element_ptr[element_num]).start_col,
- erase_mode, video_type);
- }
-
- } /* end WFL_load_form */
-
-
- /*CodeRef-mark*/
-
- long int WFL_rove_form (keyboard_code, current_element, lo, hi, increment)
- int keyboard_code;
- int *current_element;
- int lo; /* wrap around at elements lo <--> hi */
- int hi;
- int increment;
- /*
- * Mods: rework so that up and down arrows can be used to
- scroll up and down in regular 2-dimensionally arrayed form.
- The lo and hi indexes to the list must now be given and
- the increment, which is the length of one row, must be
- provided.
- For unstructured forms, use an increment of 1 (a zero or
- negative value will be over-ridden to 1).
-
- * Function updates the current_element index (i-1, i+0, or i+1)
- * for roving the elements in a form.
- * Input is a filtered keyboard_code (e.g. return code
- * from field_input()).
- * Output is the updated current_element index.
- *
- * Keyboard codes KBF_UP and KBF_PREVFIELD decrement;
- * Keyboard codes KBF_DOWN and KBF_NEXTFIELD increment;
- * Others leave current_element unchanged.
- *
- * Return value: If keyboard_code is the KBF_EXIT signal, then
- * WFL_rove_form returns TRUE, meaning done;
- * else returns FALSE, not done with a form.
- */
- /*CodeRef-mark*/
- {
- int form_done;
- int row, col;
-
- form_done = FALSE;
-
- if (increment < 1) increment = 1;
-
- if ((keyboard_code == KBF_NEXTFIELD) ||
- (keyboard_code == KBF_PREVFIELD) )
- increment = 1;
-
- switch (keyboard_code)
- {
- case KBF_DOWN:
- case KBF_NEXTFIELD:
- *current_element += increment;
- if ( *current_element > hi)
- {
- row = 0;
- col = (*current_element -lo) % increment;
- *current_element = lo +col;
- }
- break;
-
- case KBF_UP:
- case KBF_PREVFIELD:
- *current_element -= increment;
- if ( *current_element < lo)
- {
- *current_element += increment;
- row = (hi -lo) / increment;
- col = (*current_element -lo) % increment;
- *current_element = (row * increment) +col;
- if ( *current_element > hi)
- *current_element -= increment;
- }
- break;
-
-
- case KBF_EXIT: form_done = TRUE; break;
- }
-
- /******* OLDER FORMULA (THAT DOESN'T WORK PROPERLY) ****
- switch (keyboard_code)
- {
- case KBF_DOWN:
- case KBF_NEXTFIELD:
- if (*current_element == hi)
- (*current_element) = lo;
- else
- {
- *current_element += increment;
- if ( *current_element > hi)
- *current_element = lo +
- (*current_element -hi);
- }
- break;
-
- case KBF_UP:
- case KBF_PREVFIELD:
- if (*current_element == lo)
- (*current_element) = hi;
- else
- {
- *current_element -= increment;
- if ( *current_element < lo)
- *current_element = hi -
- (lo - *current_element);
- }
- break;
-
- case KBF_EXIT: form_done = TRUE; break;
- }
- ******************* END OF OLDER FORMULA *****/
-
- return (form_done);
-
- } /* end WFL_rove_form */
-
-
- /*CodeRef-mark*/
-
- void WFL_generic_form (window_ptr, element_ptr, label, data_len)
- struct window_struct *window_ptr;
- struct form_element_struct *element_ptr[];
- char label[];
- int data_len;
- /*
- * Create a form for a single element input. Used in conjuction
- * with windows to create a popup box for retrieving answer to
- * a single question.
- */
- /*CodeRef-mark*/
- {
- int element_num;
- int erase_mode;
- int video_type;
- int len;
-
- erase_mode = 0;
- video_type = NORMAL; /* changed from _ONE (BOLD) */
- element_num = 0;
-
- len = strlen(label);
- /*
- printf("label,len,row,col %s %d %d %d %d\n", label,len,
- (*element_ptr[element_num]).start_row,
- (*element_ptr[element_num]).start_col,(*window_ptr).wind_id);
- */
- put_chars((*window_ptr).wind_id,
- label, len,
- (*element_ptr[element_num]).start_row,
- (*element_ptr[element_num]).start_col,
- erase_mode, video_type);
- (*element_ptr[element_num]).length_label = len;
- (*element_ptr[element_num]).length_field = data_len;
-
- } /* end WFL_generic_form */
-
-
- /*CodeRef-mark*/
-
- void WFL_display_form_data (window_ptr, element_ptr, data, data_type,
- element_num, video_type)
- struct window_struct *window_ptr;
- struct form_element_struct *element_ptr[];
- int *data;
- int data_type;
- int element_num;
- int video_type;
- /*
- * Display form data passed by reference in "data". Uses "data_type" to
- * determine how to display and "element_num" to determine the
- * location.
- */
- /*CodeRef-mark*/
- {
- char *string_data;
- int field_len;
- int erase_mode;
- int start_col;
- int len;
- int i;
- erase_mode = 0;
-
- /* Determine space required for string to display data. */
-
- string_data = (char *)
- malloc((*element_ptr[element_num-1]).length_field);
-
- /* Determine location to put data based on size of element label */
-
- field_len = (*element_ptr[element_num-1]).length_field;
- start_col = (*element_ptr[element_num-1]).start_col +
- (*element_ptr[element_num-1]).length_label ;
-
- /* Convert data in string based on data_type. If string just copy. */
-
- fieldValToString (data, data_type, string_data, field_len);
-
- /********
- ***************/
-
- /********
- switch (data_type)
- {
- case DT_STRING:
- strncpy (string_data, data, field_len);
- break;
- case DT_LONGINT:
- sprintf (string_data, "%ld",
- *data);
- break;
- case DT_FLOAT:
- sprintf (string_data, "%f",
- *data);
- break;
- default:
- break;
- }
- ***************/
-
-
- /* Left justify string and display data into field area. */
-
- left_justify(string_data, field_len);
- len = strlen(string_data);
- for (i = len; i < field_len; i++)
- string_data[i] = ' ';
- put_chars ((*window_ptr).wind_id, string_data, field_len,
- (*element_ptr[element_num-1]).start_row,
- start_col, erase_mode, video_type);
-
- free(string_data);
-
- } /* end WFL_display_form_data */
-
-
- /*CodeRef-mark*/
-
- void WFL_read_element (window_ptr, element_ptr, data,
- data_type, element_num, rcode)
- struct window_struct *window_ptr;
- struct form_element_struct *element_ptr[];
- int *data;
- int data_type;
- int element_num;
- int *rcode;
- /*
- * Read data for form element defined by "element_num". All data
- * is initially read in as a string and then converted based on
- * "data_type". If data is going to be retrieved through the
- * use of the 'callback' feature, then it should be defined as
- * when the form is initialized. Data is returned in "data".
- */
- /*CodeRef-mark*/
- {
- char *string_data;
- int field_len;
- int start_col;
- int status;
-
- /* Check the type of element and take appropriate action. */
-
- if ((*element_ptr[element_num-1]).type == FORM_CALLBACK)
- {
- WFL_read_callback((CFP) (*element_ptr[element_num-1]).callback,
- (int *) (*element_ptr[element_num-1]).popup,
- data, rcode);
- }
- else if((*element_ptr[element_num-1]).type == MENU_CALLBACK)
- {
- WFL_read_callback(
- (CFP)(*element_ptr[element_num-1]).callback,
- (int *)(*element_ptr[element_num-1]).popup,
- data, rcode);
-
-
- /* Re-display data based on popup menu selection. */
-
- WFL_display_form_data (window_ptr, element_ptr,
- data, data_type, element_num, BOLD);
- }
-
- /*
- * DUMMY_FORM allows for entries which are for
- * info only, no input field
- */
- else if((*element_ptr[element_num-1]).type != DUMMY_FORM)
-
- {
-
- /* Reverse the data display to show user the current element. */
-
- WFL_display_form_data (window_ptr, element_ptr,
- data, data_type, element_num, REVERSE);
-
- /* Create space required for string used to retrieve the data. */
-
- string_data = (char *)
- malloc((*element_ptr[element_num-1]).length_field);
-
- /* Determine location of the data. */
-
- field_len = (*element_ptr[element_num-1]).length_field;
- start_col = (*element_ptr[element_num-1]).start_col +
- (*element_ptr[element_num-1]).length_label ;
-
- /* Convert the current value of data to string form. */
-
- fieldValToString (data, data_type, string_data, field_len);
-
- /********
- ***************/
-
- /********
- switch (data_type)
- {
- case DT_STRING:
- strncpy (string_data, data, field_len);
- break;
- case DT_LONGINT:
- sprintf (string_data, "%ld",
- *data);
- break;
- case DT_FLOAT:
- sprintf (string_data, "%f",
- *data);
- break;
- }
- ***************/
-
- left_justify(string_data, field_len);
-
- status = FALSE;
-
- /* While input is not valid get input from the user for the element. This
- loop is put in to keep the user from entering bad data. (e.g. entering
- a character when a numeric value is required.) */
-
- while (!status)
- {
- input_field ((*window_ptr).wind_id, string_data,
- (*element_ptr[element_num-1]).start_row,
- start_col, field_len, rcode);
-
- /* Try to convert string back to data of original type. */
-
- status = stringToFieldVal(data, data_type, string_data, field_len);
-
- /********
- ***************/
-
- /********
- switch (data_type)
- {
- case DT_STRING:
- strncpy (data, string_data, field_len);
- status = TRUE;
- break;
- case DT_LONGINT:
- status = sscanf (string_data, "%ld", data);
- break;
- case DT_FLOAT:
- status = sscanf (string_data, "%f", data);
- break;
-
- }
- ***************/
-
- }
-
- /* Re-display data in normal mode when completed. */
-
- WFL_display_form_data (window_ptr, element_ptr,
- data, data_type, element_num, BOLD);
-
- free(string_data);
-
- }
-
- } /* end WFL_read_element */
-
-
- /*CodeRef-mark*/
- /*
- * Functions for integrating forms and menus.
- */
-
-
- /*CodeRef-mark*/
-
- /*CodeRef-mark*/
-
- void WFL_create_popup (c)
- struct window_struct **c;
- /*
- * Create space required for a popup window structure.
- */
- /*CodeRef-mark*/
- {
- *c = (struct window_struct *) malloc(sizeof(struct window_struct));
-
- } /* end WFL_create_popup */
-
-
- /*CodeRef-mark*/
-
- void WFL_set_popup_window ( window_ptr, parent_ptr, element_ptr, element_num,
- num_elements)
- struct window_struct *window_ptr;
- struct window_struct *parent_ptr;
- struct form_element_struct *element_ptr[];
- int element_num;
- int num_elements;
- /*
- * Use information from the element of the parent form to determine
- * the size and location of the popup window. This function is used
- * in conjuction with the other 'callback' functions to create a
- * popup window for input of a form element. All the information from
- * the parent form is inherited in this window.
- */
- /*CodeRef-mark*/
- {
- int field_len;
- int start_col;
- int start_row;
-
- /* Determin size and location from the parent element. */
-
- field_len = (*element_ptr[element_num-1]).length_field;
- start_col = (*element_ptr[element_num-1]).start_col +
- (*element_ptr[element_num-1]).length_label +
- (*parent_ptr).start_col;
- start_row = (*element_ptr[element_num-1]).start_row +
- (*parent_ptr).start_row;
-
- (*window_ptr).start_row = start_row;
- (*window_ptr).start_col = start_col;
- (*window_ptr).num_cols = field_len;
- (*window_ptr).num_rows = num_elements;
- (*window_ptr).label[0] = '\0';
-
- } /* end WFL_set_popup_window */
-
-
- /*CodeRef-mark*/
-
- void WFL_popup_connect (element_ptr, element_num, context_ptr, callback_ptr)
- struct form_element_struct *element_ptr[];
- int element_num;
- int *context_ptr;
- CFP callback_ptr;
- /*
- * Connect the window structure pointer and the pointer to the function
- * to be called, when the element is selected, to the parent element.
- * This should be called when the popup window is initialized and requires
- * the parent element pointer.
- */
- /*CodeRef-mark*/
- {
- (*element_ptr[element_num-1]).popup = (char *) context_ptr;
- (*element_ptr[element_num-1]).callback = (CFP) callback_ptr;
-
- } /* end WFL_popup_connect */
-
-
- /*CodeRef-mark*/
-
- void WFL_get_popup_pointer (element_ptr, element_num, context_ptr)
- struct form_element_struct *element_ptr[];
- int element_num;
- int **context_ptr;
- /*
- * Returns the pointer to the popup window structure contained
- * in the structure of the parent form element.
- */
- /*CodeRef-mark*/
- {
- *context_ptr = (int *) (*element_ptr[element_num-1]).popup;
-
- } /* end WFL_get_popup_pointer */
-
-
-
- /*CodeRef-mark*/
-
- void WFL_read_callback(callback, popup, data, rcode)
- CFP callback;
- int *popup;
- int *data;
- int *rcode;
- /*
- * Call back application with appropriate function to retrieve the
- * data needed for the parent element. This function is called as
- * subordinate function of WFL package. The application should
- * never call this function.
- */
- /*CodeRef-mark*/
- {
- (*callback) (popup, data, rcode);
-
- } /* end WFL_read_callback */
-
-
-
- /*CodeRef-mark*/
-
- long int WFL_popup_info ( startRow, startCol, maxRows,
- banner, element_list, window_ptr)
- int startRow;
- int startCol;
- int maxRows;
- char *banner;
- char *element_list[];
- struct window_struct **window_ptr;
- /*
- * Popup an info message on-the-fly.
- * Caller must erase and deallocate the window.
- * Return value: status of
- */
- /*CodeRef-mark*/
- {
- int stat;
-
- stat = WFL_new_dyna_window (window_ptr, banner);
-
- WFL_set_dyna_window (startRow, startCol, maxRows,
- element_list, *window_ptr);
-
- WFL_put_dyna_info (*window_ptr, element_list);
-
- return (stat);
- } /* end WFL_popup_info */
-
-
-
- /*CodeRef-mark*/
-
- void WFL_put_dyna_info (window_ptr, element_list)
- struct window_struct *window_ptr;
- char *element_list[];
- /*
- * This function puts the element list in the info window.
- */
- /*CodeRef-mark*/
- {
- int num_elements = string_count(element_list);
- struct menu_element_struct **tempMenu;
-
- WFL_draw_window (window_ptr);
-
- tempMenu = WFL_new_dyna_menu (element_list);
-
- WFL_load_menu (tempMenu, num_elements, window_ptr, 0, 0);
-
- WFL_delete_dyna_menu (tempMenu, element_list);
-
- } /* end WFL_put_dyna_info */
-
-
-
- /*CodeRef-mark*/
-
-